use axum::{
    extract::{Extension, Json},
    response::Json as JsonResponse,
};

use sqlx::MySqlPool;

use crate::{
    errors::AppError,
    models::{AuthResponse, CreateUser, LoginUser, User},
    repositories::user_repository::{create_user,find_user_by_email,get_all_users,get_user_by_id},
    services::auth::{create_jwt, verify_password},
};


pub async fn create_user_handler(
    Extension(pool): Extension<MySqlPool>,
    Json(user): Json<CreateUser>,
) -> Result<JsonResponse<AuthResponse>, AppError> {
    let hash_password = bcrypt::hash(user.password, bcrypt::DEFAULT_COST)
    .map_err(|_| AppError::InternalServerError("Error hashing password".to_string()))?;
    let user = create_user(&pool, &user.username, &user.email, &hash_password).await?;
    let token = create_jwt(&user.id)?;
    
    Ok(JsonResponse(AuthResponse { token, user }))
}

pub async fn login_handler(
    Extension(pool): Extension<MySqlPool>,
    Json(user): Json<LoginUser>,
) -> Result<JsonResponse<AuthResponse>, AppError> {
    let user = find_user_by_email(&pool, &user.email).await?;
    //.ok_or(AppError::Unauthorized("Invalid email or password".to_string()))?;

    let is_valid = verify_password(&user.password_hash, &user.password_hash)?;
    if !is_valid {
        return Err(AppError::Unauthorized("Invalid email or password".to_string()));
    }

    let token = create_jwt(&user.id)?;

    Ok(JsonResponse(AuthResponse { token, user }))
}

pub async fn get_all_users_handler(
    Extension(pool): Extension<MySqlPool>,
) -> Result<JsonResponse<Vec<User>>, AppError> {
    let users = get_all_users(&pool).await?;
    Ok(JsonResponse(users))
}

pub async fn get_user_by_id_handler(
    Extension(pool): Extension<MySqlPool>,
    Json(id): Json<String>,
) -> Result<JsonResponse<User>, AppError> {
    let user = get_user_by_id(&pool, &id).await?;
    Ok(JsonResponse(user))
}   

pub async fn get_current_user(
    Extension(user): Extension<User>,
) -> Result<JsonResponse<User>, AppError> {
    Ok(JsonResponse(user))
}